﻿/*********************************************************
 * 开发人员：小兵
 * 创建时间：2012-10-9 15:58:09
 * 描述说明：
 * 
 * 更改历史：
 * 
 * *******************************************************/
namespace Mozlite.Data.MySql
{
    using System;
    using System.Web;
    using System.Data;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;

    /// <summary>
    /// MYSQL数据库解析类。
    /// </summary>
    public class MySqlParser : SqlParser
    {
        /// <summary>
        /// 初始化类<see cref="MySqlParser"/>。
        /// </summary>
        public MySqlParser()
            : base(new char[] { '[', ']', '@' }, new char[] { '`', '`', '?' })
        { }

        /// <summary>
        /// 解析SQL语句，并实行替换。
        /// </summary>
        /// <param name="query">查询语句。</param>
        /// <returns>替换修改后的语句。</returns>
        /// <remarks>
        /// 默认直接返回当前SQL语句，子类重写进行替换。
        /// </remarks>
        public override string Parse(string query)
        {
            return UppercaseIdentifiers(ReplaceIdentifierTokens(query));
        }

        //将SELECT TOP(N)格式转换为LIMIT格式；
        private static readonly Regex selectTopN = new Regex(@"SELECT TOP\s*\(?(\d+)\)?", RegexOptions.Compiled | RegexOptions.Singleline);
        //将IF EXISTS UPDATE INSERT INTO转换为INSERT INTO ON DUPLICATE KEY UPDATE格式；
        private static readonly Regex saveStatement = new Regex(@"^if\s*\(?exists\s*\(?.*?(begin|\r?\n)\s*update.*?set(.*?)where.*?(\r?\n?end|\r?\n)\s*else\s*(begin|\r?\n)\s*(insert into.*?);?(\s*|\r?\n?)(end)?(\s*|\r?\n?)$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

        /// <summary>
        /// 替换关键字，如：GETDATE和NOW等等，所有替换在转换大写后进行。
        /// </summary>
        /// <param name="query">SQL语句。</param>
        /// <returns>返回替换后的字符串。</returns>
        protected override string SyntaxReplace(string query)
        {
            if (string.IsNullOrEmpty(query))
                return string.Empty;
            //日期函数替换；
            query = query.Replace("GETDATE", "NOW").Trim();
            //将SELECT TOP(N)格式转换为LIMIT格式；
            if (selectTopN.IsMatch(query))
            {
                var size = selectTopN.Match(query).Groups[1].Value;
                query = selectTopN.Replace(query, "SELECT");
                var index = query.IndexOf(';');
                if (index != -1)
                    query = query.Insert(index, " LIMIT " + size);
                else
                    query += " LIMIT " + size + ";";
            }
            //将IF EXISTS UPDATE INSERT INTO转换为INSERT INTO ON DUPLICATE KEY UPDATE格式；
            if (saveStatement.IsMatch(query))
            {
                query = saveStatement.Replace(query, "$5 ON DUPLICATE KEY UPDATE $2;");
            }
            return query;
        }
    }
}